/********************************************************************************************
* Header defining the APIs for AES
*
* If USE_OPENSSL flag is defined it uses OpenSSL's AES implementation. 
* Otherwise, it uses a standalone implementation
*********************************************************************************************/

#ifndef __AES_H
#define __AES_H

#include <stdint.h>
#include <stdlib.h>
#include "../config.h"


#ifndef USE_OPENSSL
/**
 * Function to fill a key schedule given an initial key.
 *
 * @param key            Initial Key.
 * @param schedule       Abstract data structure for a key schedule.
 */
void AES128_load_schedule(const uint8_t *key, uint8_t *schedule);

/**
 * Same as AES128_ECB_enc() except a schedule generated by
 * AES128_load_schedule() is passed rather than a key. This is faster
 * if the same schedule is used for multiple encryptions since it does
 * not have to be regenerated from the key.
 */
void AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *schedule, uint8_t *ciphertext);

/**
 * Function to free a key schedule.
 *
 * @param schedule       Schedule generated with AES128_load_schedule().
 */
void AES128_free_schedule(uint8_t *schedule);

/**
 * Function to fill a key schedule given an initial key.
 *
 * @param key            Initial Key.
 * @param schedule       Abstract data structure for a key schedule.
 */
void AES256_load_schedule(const uint8_t *key, uint8_t *schedule);

/**
 * Same as AES256_ECB_enc() except a schedule generated by
 * AES256_load_schedule() is passed rather than a key. This is faster
 * if the same schedule is used for multiple encryptions since it does
 * not have to be regenerated from the key.
 */
void AES256_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *schedule, uint8_t *ciphertext);

/**
 * Function to free a key schedule.
 *
 * @param schedule       Schedule generated with AES256_load_schedule().
 */
void AES256_free_schedule(uint8_t *schedule);

#else  // Use OpenSSL's AES implementation

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
void handleErrors(void);
void AES128_free_schedule(EVP_CIPHER_CTX *schedule);
void AES256_free_schedule(EVP_CIPHER_CTX *schedule);

#endif

#endif
